package com.xxx.common.shardingsphere.aop;

import com.xxx.common.base.constants.MdcKey;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.infra.hint.HintManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;


@Aspect
@Component
@EnableAspectJAutoProxy
public class TenantDSAop {

    @Pointcut("execution(* *..mapper.*Mapper.*(..))")
    public void pc() {
    }

    @Around("pc()")
    public Object round(ProceedingJoinPoint point) {
        try {

            if (HintManager.isInstantiated()) {
                return point.proceed();
            }

            //需要配置 hint 的分库或者分表策略，才会走到强制路由
            try (HintManager hintManager = HintManager.getInstance()) {
                String dsName = "ds" + MDC.get(MdcKey.TENANT_ID);
                String tableName = MDC.get(MdcKey.TABLE_NAME);
                if (StringUtils.isBlank(tableName)) {//自动分库
                    hintManager.setDatabaseShardingValue(dsName);
                } else {//指定库和指定表
                    String[] split = splitTableName(tableName);
                    hintManager.addDatabaseShardingValue(split[0], dsName);
                    hintManager.addTableShardingValue(split[0], Integer.valueOf(split[1]));
                }
                return point.proceed();
            }
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    private String[] splitTableName(String tableName) {
        // 使用正则表达式匹配数字和非数字部分
        String[] parts = tableName.split("_(?=\\d+$)");

        // 如果没有数字后缀，返回整个表名和空字符串
        if (parts.length == 1) {
            return new String[]{parts[0], ""};
        }
        return parts;
    }
}
